﻿namespace MicroCloud.Utils
{
    /// <summary>
    /// 时间扩展操作类
    /// </summary>
    public static class DateTimeExtensions
    {
        /// <summary>
        /// 当前时间是否周末
        /// </summary>
        /// <param name="dateTime">时间点</param>
        /// <returns></returns>
        public static bool IsWeekend(this DateTime dateTime)
        {
            DayOfWeek[] weeks = { DayOfWeek.Saturday, DayOfWeek.Sunday };
            return weeks.Contains(dateTime.DayOfWeek);
        }

        /// <summary>
        /// 当前时间是否工作日
        /// </summary>
        /// <param name="dateTime">时间点</param>
        /// <returns></returns>
        public static bool IsWeekday(this DateTime dateTime)
        {
            DayOfWeek[] weeks = { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday };
            return weeks.Contains(dateTime.DayOfWeek);
        }

        /// <summary>
        /// 获取时间相对唯一字符串
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="milsec">是否使用毫秒</param>
        /// <returns></returns>
        public static string ToUniqueString(this DateTime dateTime, bool milsec = false)
        {
            int seconds = dateTime.Hour * 3600 + dateTime.Minute * 60 + dateTime.Second;
            string value = $"{dateTime:yy}{dateTime.DayOfYear}{seconds}";
            return milsec ? value + dateTime.ToString("fff") : value;
        }

        /// <summary>
        /// 将时间转换为JS时间格式(Date.getTime())
        /// </summary>
        /// <param name="dateTime">日期时间对象</param>
        /// <param name="milsec">时间单位（秒/毫秒），默认毫秒</param>
        /// <returns></returns>
        public static string ToJsGetTime(this DateTime dateTime, bool milsec = true)
        {
            DateTime utc = dateTime.ToUniversalTime();
            TimeSpan span = utc.Subtract(new DateTime(1970, 1, 1));
            return Math.Round(milsec ? span.TotalMilliseconds : span.TotalSeconds).ToString();
        }

        /// <summary>
        /// 将JS时间格式的数值转换为时间
        /// </summary>
        /// <param name="jsTime"></param>
        /// <returns></returns>
        public static DateTime FromJsGetTime(this long jsTime)
        {
            int length = jsTime.ToString().Length;
            Check.Required<ArgumentException>(length == 10 || length == 13, I18N.T("JS时间数值的长度必须为 10 位或 13 位"));
            DateTime start = new(1970, 1, 1);
            DateTime result = length == 10 ? start.AddSeconds(jsTime) : start.AddMilliseconds(jsTime);
            return result.ToUniversalTime();
        }

        /// <summary>
        /// 将当前时区时间转换为UTC时间
        /// </summary>
        public static DateTime ToUtcTime(this DateTime dateTime)
        {
            return dateTime.ToUniversalTime();
        }

        /// <summary>
        /// 将指定UTC时间转换为当前时区的时间
        /// </summary>
        public static DateTime FromUtcTime(this DateTime dateTime)
        {
            return dateTime.ToLocalTime();
        }

        /// <summary>
        /// 根据签约时间和签约时长来判断是否到期
        /// </summary>
        /// <param name="joinDate">签约时间</param>
        /// <param name="duration">签约时长</param>
        /// <param name="durationType">签约时长类型（默认分钟）</param>
        /// <returns></returns>
        public static bool IsExprired(this DateTime joinDate, double duration, DurationType durationType = DurationType.Minutes)
        {
            joinDate = joinDate.ToUniversalTime();
            var currentDate = DateTime.Now.ToUniversalTime();
            var timeSpanVal = TimeSpan.Zero;
            switch (durationType)
            {
                case DurationType.Milliseconds:
                    timeSpanVal = TimeSpan.FromMilliseconds(duration);
                    break;
                case DurationType.Seconds:
                    timeSpanVal = TimeSpan.FromSeconds(duration);
                    break;
                case DurationType.Minutes:
                    timeSpanVal = TimeSpan.FromMinutes(duration);
                    break;
                case DurationType.Hours:
                    timeSpanVal = TimeSpan.FromHours(duration);
                    break;
                case DurationType.Days:
                    timeSpanVal = TimeSpan.FromDays(duration);
                    break;
            }
            return currentDate - joinDate > timeSpanVal;
        }

        /// <summary>
        /// 获取中国历法
        /// </summary>
        /// <param name="dateTime">日期时间</param>
        /// <param name="gregorianCalendarDate">是否公历日期</param>
        /// <returns></returns>
        public static ChineseCalendar ToChineseCalendar(this DateTime dateTime, bool gregorianCalendarDate = true)
        {
            return new ChineseCalendar(dateTime, gregorianCalendarDate);
        }
 
    }
}